/**
 * @file CRhoTable.cpp Implementácia triedy CRhoTable.
 *
 * @author Martin Kosorinský.
 * @date 1.4.2009.
 */

#include "CRhoTable.hpp"

CRhoTable::CRhoTable() {
}

CRhoTable::CRhoTable(const CRhoTable &tab) {
    CRhoTable::const_iterator it;
    for (it = tab.begin(); it != tab.end(); it++) {
        this->add(it->first, it->second.first, it->second.second);
    }
}

CRhoTable::~CRhoTable() {
    this->clear();
}

CRhoTable& CRhoTable::operator=(const CRhoTable & tab) {
    CRhoTable::const_iterator it;
    this->clear();
    for (it = tab.begin(); it != tab.end(); it++) {
        this->add(it->first, it->second.first, it->second.second);
    }
    return *this;
};

void CRhoTable::add(const epoint * P, const big a, const big b) {
    epoint * point = epoint_init();
    epoint_copy((epoint*)P, point);
    big aa = mirvar(0);
    big bb = mirvar(0);
    copy((big)a, aa);
    copy((big)b, bb);
    table.insert(std::pair<epoint*, std::pair<big, big> >(point, std::make_pair(aa, bb)));
};

void CRhoTable::add(const big x, const big y, const big a, const big b) {
    epoint * point = epoint_init();
    if (!epoint_set(x, y, 0, point)) {
        cerr << "Error: '" << __FUNCTION__ << "': Bod nelezi na krivke!" << endl;
        exit(1);
    }
    big aa = mirvar(0);
    big bb = mirvar(0);
    copy((big)a, aa);
    copy((big)b, bb);
    table.insert(std::pair<epoint*, std::pair<big, big> >(point, std::make_pair(aa, bb)));
};

void CRhoTable::clear() {
    iterator it;
    for (it = table.begin(); it != table.end(); it++) {
        mirkill(it->second.first);
        mirkill(it->second.second);
        epoint_free(it->first);
    }
    table.clear();
}

bool CRhoTable::save(std::string fileName) {
    bool retVal = true;
    CRhoTable::const_iterator it;

    char buffer[256];
    char sign;
    unsigned char size;
    unsigned long int tabSize = this->size();

    big x = mirvar(0);
    big y = mirvar(0);

    ofstream out(fileName.c_str(), ofstream::binary);
    out.write((char*)&tabSize, sizeof(tabSize));
    if (out.good()) {
        for (it = this->begin(); it != this->end(); it++) {
            epoint_get(it->first, x, y);
            size = (unsigned char) big_to_bytes(256, x, buffer, FALSE);
            sign = (char) exsign(x);
            out.write((char*)&sign, 1);
            out.write((char*)&size, 1);
            out.write(buffer, size);
            size = (unsigned char) big_to_bytes(256, y, buffer, FALSE);
            sign = (char) exsign(y);
            out.write((char*)&sign, 1);
            out.write((char*)&size, 1);
            out.write(buffer, size);
            size = (unsigned char) big_to_bytes(256, it->second.first, buffer, FALSE);
            sign = (char) exsign(it->second.first);
            out.write((char*)&sign, 1);
            out.write((char*)&size, 1);
            out.write(buffer, size);
            size = (unsigned char) big_to_bytes(256, it->second.second, buffer, FALSE);
            sign = (char) exsign(it->second.second);
            out.write((char*)&sign, 1);
            out.write((char*)&size, 1);
            out.write(buffer, size);
        }
    }
    else {
        cerr << "Error: '" << __FUNCTION__ << "': Chyba pri zapise tabulky do suboru!" << endl;
        retVal = false;
    }
    out.close();

    mirkill(x);
    mirkill(y);

    return retVal;
}

bool CRhoTable::load(std::string fileName) {
    bool retVal = true;
    CRhoTable::const_iterator it;

    char buffer[256];
    char sign;
    unsigned char size;
    unsigned long int tabSize;

    big x = mirvar(0);
    big y = mirvar(0);
    big a = mirvar(0);
    big b = mirvar(0);
    epoint * P = epoint_init();

    ifstream in(fileName.c_str(), ofstream::binary);
    in.read((char*)&tabSize, sizeof(tabSize));
    if (in.good()) {
        for (int i = 0; i < (int)tabSize; i++) {
            in.read((char*)&sign, 1);
            in.read((char*)&size, 1);
            in.read((char*)buffer, size);
            bytes_to_big(size, buffer, x);
            insign(sign, x);
            in.read((char*)&sign, 1);
            in.read((char*)&size, 1);
            in.read((char*)buffer, size);
            bytes_to_big(size, buffer, y);
            insign(sign, y);
            in.read((char*)&sign, 1);
            in.read((char*)&size, 1);
            in.read((char*)buffer, size);
            bytes_to_big(size, buffer, a);
            insign(sign, a);
            in.read((char*)&sign, 1);
            in.read((char*)&size, 1);
            in.read((char*)buffer, size);
            bytes_to_big(size, buffer, b);
            insign(sign, b);
            this->add(x, y, a, b);
        }
    }
    else {
        cerr << "Error: '" << __FUNCTION__ << "': Chyba pri nacitani tabulky zo suboru!" << endl;
        retVal = false;
    }
    in.close();

    epoint_free(P);
    mirkill(x);
    mirkill(y);
    mirkill(a);
    mirkill(b);
    return retVal;
}
